package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"sync"
)

// ProgressTracker 跟踪上传进度
type ProgressTracker struct {
	Total   int64
	Current int64
	mutex   sync.RWMutex
}

// Write 实现io.Writer接口
func (pt *ProgressTracker) Write(p []byte) (int, error) {
	pt.mutex.Lock()
	defer pt.mutex.Unlock()
	n := len(p)
	pt.Current += int64(n)
	return n, nil
}

// GetProgress 获取进度百分比
func (pt *ProgressTracker) GetProgress() float64 {
	pt.mutex.RLock()
	defer pt.mutex.RUnlock()
	if pt.Total <= 0 {
		return 0
	}
	return float64(pt.Current) / float64(pt.Total) * 100
}

// GetProgressInfo 获取进度信息
func (pt *ProgressTracker) GetProgressInfo() (current, total int64, percent float64) {
	pt.mutex.RLock()
	defer pt.mutex.RUnlock()
	current = pt.Current
	total = pt.Total
	if pt.Total <= 0 {
		percent = 0
	} else {
		percent = float64(pt.Current) / float64(pt.Total) * 100
	}
	return
}

// handleFileUploadWithProgress 处理带进度的普通文件上传
func handleFileUploadWithProgress(w http.ResponseWriter, r *http.Request) (string, error) {
	// 解析表单
	err := r.ParseMultipartForm(32 << 20) // 32MB max memory
	if err != nil {
		return "", fmt.Errorf("failed to parse form: %v", err)
	}

	// 获取文件
	file, handler, err := r.FormFile("uploadfile")
	if err != nil {
		return "", fmt.Errorf("error retrieving file: %v", err)
	}
	defer file.Close()

	// 创建上传目录（如果不存在）
	uploadDir := "/data/servers/upload/file"
	if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
		err := os.MkdirAll(uploadDir, 0755)
		if err != nil {
			return "", fmt.Errorf("failed to create upload directory: %v", err)
		}
	}

	// 创建目标文件
	targetFile := filepath.Join(uploadDir, handler.Filename)
	dst, err := os.Create(targetFile)
	if err != nil {
		return "", fmt.Errorf("failed to create target file: %v", err)
	}
	defer dst.Close()

	// 创建进度跟踪器
	progress := &ProgressTracker{
		Total: handler.Size,
	}

	// 使用MultiWriter同时写入文件和跟踪进度
	writer := io.MultiWriter(dst, progress)

	// 复制文件内容
	_, err = io.Copy(writer, file)
	if err != nil {
		return "", fmt.Errorf("failed to save file: %v", err)
	}

	fmt.Printf("File uploaded successfully: %s\n", targetFile)
	return targetFile, nil
}

// handleJarUploadWithProgress 处理带进度的Jar文件上传
func handleJarUploadWithProgress(w http.ResponseWriter, r *http.Request) (string, error) {
	// 解析表单
	err := r.ParseMultipartForm(100 << 20) // 100MB max memory
	if err != nil {
		return "", fmt.Errorf("failed to parse form: %v", err)
	}

	// 获取文件
	file, handler, err := r.FormFile("jarfile")
	if err != nil {
		return "", fmt.Errorf("error retrieving jar file: %v", err)
	}
	defer file.Close()

	// 创建上传目录（如果不存在）
	uploadDir := "/data/servers/upload/jarfile"
	if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
		err := os.MkdirAll(uploadDir, 0755)
		if err != nil {
			return "", fmt.Errorf("failed to create jar upload directory: %v", err)
		}
	}

	// 创建目标文件
	targetFile := filepath.Join(uploadDir, handler.Filename)
	dst, err := os.Create(targetFile)
	if err != nil {
		return "", fmt.Errorf("failed to create target jar file: %v", err)
	}
	defer dst.Close()

	// 创建进度跟踪器
	progress := &ProgressTracker{
		Total: handler.Size,
	}

	// 使用MultiWriter同时写入文件和跟踪进度
	writer := io.MultiWriter(dst, progress)

	// 复制文件内容
	_, err = io.Copy(writer, file)
	if err != nil {
		return "", fmt.Errorf("failed to save jar file: %v", err)
	}

	fmt.Printf("Jar file uploaded successfully: %s\n", targetFile)
	return targetFile, nil
}

// handleFrontendUploadWithProgress 处理带进度的前端文件上传
func handleFrontendUploadWithProgress(w http.ResponseWriter, r *http.Request) (string, error) {
	// 解析表单
	err := r.ParseMultipartForm(100 << 20) // 100MB max memory
	if err != nil {
		return "", fmt.Errorf("failed to parse form: %v", err)
	}

	// 获取文件
	file, handler, err := r.FormFile("frontendfile")
	if err != nil {
		return "", fmt.Errorf("error retrieving frontend file: %v", err)
	}
	defer file.Close()

	// 创建上传目录（如果不存在）
	uploadDir := "/data/servers/upload/frontend"
	if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
		err := os.MkdirAll(uploadDir, 0755)
		if err != nil {
			return "", fmt.Errorf("failed to create frontend upload directory: %v", err)
		}
	}

	// 创建目标文件
	targetFile := filepath.Join(uploadDir, handler.Filename)
	dst, err := os.Create(targetFile)
	if err != nil {
		return "", fmt.Errorf("failed to create target frontend file: %v", err)
	}
	defer dst.Close()

	// 创建进度跟踪器
	progress := &ProgressTracker{
		Total: handler.Size,
	}

	// 使用MultiWriter同时写入文件和跟踪进度
	writer := io.MultiWriter(dst, progress)

	// 复制文件内容
	_, err = io.Copy(writer, file)
	if err != nil {
		return "", fmt.Errorf("failed to save frontend file: %v", err)
	}

	fmt.Printf("Frontend file uploaded successfully: %s\n", targetFile)
	return targetFile, nil
}
